home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 9181 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.0 KB  |  114 lines

  1. Newsgroups: comp.lang.c
  2. Path: news.sprintlink.net!eskimo!scs
  3. From: scs@eskimo.com (Steve Summit)
  4. Subject: Re: Q: tokenizing
  5. X-Nntp-Posting-Host: eskimo.com
  6. Message-ID: <DnyKI7.Ezn@eskimo.com>
  7. Sender: news@eskimo.com (News User Id)
  8. Organization: schmorganization
  9. References: <maguirer.826209754@hercules>
  10. Date: Fri, 8 Mar 1996 16:58:54 GMT
  11.  
  12. In article <maguirer.826209754@hercules>, maguirer@HERCULES.CS.UREGINA.CA
  13. (Rob Maguire) writes:
  14. > Have read the FAQ and found the question where it talks about separating a
  15. > string into tokens split by white-space.  The answer is to use 'strtok'.
  16. > OK...  How?
  17.  
  18. The posted FAQ list is far too long already, so it does not
  19. always contain as many worked-out examples as perhaps it should.
  20. Here's the full-blown answer from the book version, where I had
  21. more room to play with:
  22.  
  23. 13.6:    How can I split up a string into whitespace-separated fields?
  24.     How can I duplicate the process by which main() is handed argc
  25.     and argv?
  26.  
  27. A:    The only Standard routine available for this kind of
  28.     "tokenizing" is strtok, although it can be tricky to use [1] and
  29.     it may not do everything you want it to.  (For instance, it does
  30.     not handle quoting.)  Here is a usage example, which simply
  31.     prints each field as it's extracted:
  32.  
  33.         #include <string.h>
  34.         char string[] = "this is a test";   /* not char *; see Q 16.6 */
  35.         char *p;
  36.         for(p = strtok(string, " \t\n"); p != NULL;
  37.                     p = strtok(NULL, " \t\n"))
  38.             printf("\"%s\"\n", p);
  39.  
  40.     As an alternative, here is a routine I use for building an argv
  41.     all at once:
  42.  
  43.         #include <ctype.h>
  44.  
  45.         int makeargv(char *string, char *argv[], int argvsize)
  46.         {
  47.             char *p = string;
  48.             int  i;
  49.             int argc = 0;
  50.  
  51.             for(i = 0; i < argvsize; i++) {
  52.             /* skip leading whitespace */
  53.             while(isspace(*p))
  54.                 p++;
  55.  
  56.             if(*p != '\0')
  57.                 argv[argc++] = p;
  58.             else {
  59.                 argv[argc] = 0;
  60.                 break;
  61.             }
  62.  
  63.             /* scan over arg */
  64.             while(*p != '\0' && !isspace(*p))
  65.                 p++;
  66.             /* terminate arg: */
  67.             if(*p != '\0' && i < argvsize-1)
  68.                 *p++ = '\0';
  69.             }
  70.  
  71.             return argc;
  72.         }
  73.  
  74.     Calling makeargv() is straightforward:
  75.  
  76.         char *av[10];
  77.         int i, ac = makeargv(string, av, 10);
  78.         for(i = 0; i < ac; i++)
  79.             printf("\"%s\"\n", av[i]);
  80.  
  81.     If you want each separator character to be significant, for
  82.     instance if you want two tabs in a row to indicate an omitted
  83.     field, it's probably more straightforward to use strchr():
  84.  
  85.         #include <string.h>
  86.  
  87.         char *p = string;
  88.  
  89.         while(1) {            /* break in middle */
  90.             char *p2 = strchr(p, '\t');
  91.             if(p2 != NULL)
  92.             *p2 = '\0';
  93.             printf("\"%s\"\n", p);
  94.             if(p2 == NULL)
  95.             break;
  96.             p = p2 + 1;
  97.         }
  98.  
  99.     All the code fragments presented here modify the input string,
  100.     by inserting \0's to terminate each field.  If you'll need the
  101.     original string later, make a copy before breaking it up.
  102.  
  103.     References: K&R2 Sec. B3 p. 250
  104.     ANSI Sec. 4.11.5.8
  105.     ISO Sec. 7.11.5.8
  106.     H&S Sec. 13.7 pp. 333-4
  107.     PCS p. 178
  108.  
  109.                     Steve Summit
  110.                     scs@eskimo.com
  111. __________
  112. 1.  Also, strtok() relies on some internal state during a series of
  113.     calls, and is therefore not reentrant.
  114.